package com.atguigu.tingshu.account.service.impl;

import com.atguigu.tingshu.account.mapper.UserAccountDetailMapper;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.model.account.UserAccountDetail;
import com.atguigu.tingshu.vo.account.AccountLockVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private UserAccountDetailMapper userAccountDetailMapper;

    @Override
    public void addUserAccount(Long userId) {
        // user_account
        UserAccount userAccount = new UserAccount();
        userAccount.setUserId(userId);
        userAccount.setTotalAmount(new BigDecimal("100.00"));
        userAccount.setAvailableAmount(new BigDecimal("100.00"));
        userAccountMapper.insert(userAccount);
    }

    @Override
    public BigDecimal getAvailableAmount(Long userId) {
        //根据用户Id 获取到用户余额对象
        UserAccount userAccount = this.getOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, userId));
        return userAccount.getAvailableAmount();
    }

    @Transactional
    @Override
    public int checkAndLock(AccountLockVo accountLockVo) {
        int count = userAccountMapper.checkAndLock(accountLockVo.getUserId(), accountLockVo.getAmount());
        //判断
        if (count == 0) {
            throw new GuiguException(400, "账户余额不足！");
        }
        //记录明细
        //  记录明细
        this.addUserAccountDetail(
                accountLockVo.getUserId(),
                accountLockVo.getContent(),
                SystemConstant.ACCOUNT_TRADE_TYPE_MINUS,
                accountLockVo.getAmount(),
                accountLockVo.getOrderNo()
        );
        //  返回受影响的行数
        return count;
    }

    /**
     * 记录用户账户信息
     *
     * @param userId
     * @param title
     * @param tradeType
     * @param amount
     * @param orderNo
     */
    private void addUserAccountDetail(Long userId, String title, String tradeType, BigDecimal amount, String orderNo) {
        UserAccountDetail userAccountDetail = new UserAccountDetail();
        userAccountDetail.setUserId(userId);
        userAccountDetail.setTitle(title);
        userAccountDetail.setTradeType(tradeType);
        userAccountDetail.setAmount(amount);
        userAccountDetail.setOrderNo(orderNo);
        userAccountDetailMapper.insert(userAccountDetail);
    }

    @Override
    public void add(Long userId, BigDecimal amount, String orderNo, String tradeType, String title) {
        //查看是否有当前对象
        Long count = userAccountDetailMapper.selectCount(new LambdaQueryWrapper<UserAccountDetail>().eq(UserAccountDetail::getOrderNo, orderNo));
        if (count > 0) return;
        //添加账号金额
        userAccountMapper.add(userId, amount);
        //添加明细
        this.addUserAccountDetail(userId, title, tradeType, amount, orderNo);
    }

    @Override
    public IPage<UserAccountDetail> findUserRechargePage(IPage<UserAccountDetail> pageParam, Long userId) {
        //调用mapper层方法
        return userAccountDetailMapper.selectUserRechargePage(pageParam, userId);
    }

    @Override
    public IPage<UserAccountDetail> findUserConsumePage(IPage<UserAccountDetail> pageParam, Long userId) {
        //调用mapper层方法
        return userAccountDetailMapper.selectUserConsumePage(pageParam, userId);
    }
}
